// **************************************************************
// COPYRIGHT(c)2020, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    :  
// Module name  :  
// Full name    :  
// Time         : 2020 
// Author       : Haoxiaofei 
// Email        : 1851804419@qq.com
// Data         : 
// Version      : V 1.0 
// 
// Abstract     :
// Called by    :  
// 
// Modification history
// -----------------------------------------------------------------
// 
// 
//
// *****************************************************************
// 
// 
//
// *****************************************************************

// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// INFORMATION
// *******************

//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
//*******************
//将匹配结果转化为指令
module match2action_pkt_85(
    input wire clk,
    input wire rst_n,
    input wire match_en,
    input wire[31:0] match_res,

    output reg[84:0] action_o,
    output reg action_en_o,
    // output wire layend_read,

    //和cpu接口
    input wire        cpu_wen,
    input wire        cpu_ren,
    input wire[6:0]  ram_addr,
    // input wire[15:0]  ram_addr,
    input wire[31:0]  ram_data,
    output reg        read_data_valid,
    output reg[31:0]  read_data_cpu

    ); 

//*******************
//DEFINE LOCAL PARAMETER
//*******************
//parameter(s)

             
                                    

 

//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
reg[4:0] addr;  
// reg[15:0] id_reg;
reg rd_en,rd_en_d1;
(*mark_debug = "true"*) reg no_match;
(*mark_debug = "true"*) reg no_match_d1;
reg [6:0]ram_addra;
reg [6:0]ram_addra_ff;
//WIRES

wire wea;
wire[6:0] addra;
wire[4:0] addrb;
wire[84:0] douta,doutb;
reg [84:0] dina;

reg  wea_ff;
reg  cpu_ren_ff;
//*********************
//INSTANTCE MODULE
//*********************

 
 

//*********************
//MAIN CORE
//*********************
always@(posedge clk or negedge rst_n)
begin
  if(~rst_n)
    action_en_o <= 1'd0;
  else if(rd_en_d1)
    action_en_o <= 1'b1;
  else if(no_match_d1)
    action_en_o <= 1'b1;
  else 
    action_en_o <= 1'd0;     
end 
always@(posedge clk or negedge rst_n)
  if(~rst_n)
    action_o <= 85'd0;
  else if(rd_en_d1)
    action_o <= doutb;
  else if(no_match_d1)
    action_o <= 85'h0;
  else 
    action_o <= 85'h0;
always@(posedge clk or negedge rst_n)
begin
  if(~rst_n)
    no_match <= 1'b0;
  else if(match_res==32'h0 && match_en)
    no_match <= 1'b1;
  else 
    no_match <= 1'b0;  
end 

always@(posedge clk or negedge rst_n)
begin
  if(~rst_n)
    no_match_d1 <= 1'b0;
  else 
    no_match_d1 <= no_match;
end

always@(posedge clk or negedge rst_n)
begin
  if(~rst_n)
    rd_en_d1 <= 1'b0;
  else 
    rd_en_d1 <= rd_en;
end
// assign layend_read = no_match_d1| rd_en_d1;
always@(posedge clk or negedge rst_n)
  if(~rst_n)
  begin 
    addr <= 5'd0;
    rd_en<= 1'b0;
  end 
  else if(match_en)
    if(match_res[31])
      begin
        addr <= 5'd0;
        rd_en<= 1'b1;
      end
    else if(match_res[30])
      begin
        addr <= 5'd1;
        rd_en<= 1'b1;
      end
    else if(match_res[29])
      begin
        addr <= 5'd2;
        rd_en<= 1'b1;
      end
    else if(match_res[28])
      begin
        addr <= 5'd3;
        rd_en<= 1'b1;
      end
    else if(match_res[27])
      begin
        addr <= 5'd4;
        rd_en<= 1'b1;
      end
    else if(match_res[26])
      begin
        addr <= 5'd5;
        rd_en<= 1'b1;
      end
    else if(match_res[25])
      begin
        addr <= 5'd6;
        rd_en<= 1'b1;
      end
    else if(match_res[24])
      begin
        addr <= 5'd7;
        rd_en<= 1'b1;
      end
    else if(match_res[23])
      begin
        addr <= 5'd8;
        rd_en<= 1'b1;
      end
    else if(match_res[22])
      begin
        addr <= 5'd9;
        rd_en<= 1'b1;
      end
    else if(match_res[21])
      begin
        addr <= 5'd10;
        rd_en<= 1'b1;
      end
    else if(match_res[20])
      begin
        addr <= 5'd11;
        rd_en<= 1'b1;
      end
    else if(match_res[19])
      begin
        addr <= 5'd12;
        rd_en<= 1'b1;
      end
    else if(match_res[18])
      begin
        addr <= 5'd13;
        rd_en<= 1'b1;
      end
    else if(match_res[17])
      begin
        addr <= 5'd14;
        rd_en<= 1'b1;
      end
    else if(match_res[16])
      begin
        addr <= 5'd15;
        rd_en<= 1'b1;
      end
    else if(match_res[15])
      begin
        addr <= 5'd16;
        rd_en<= 1'b1;
      end
    else if(match_res[14])
      begin
        addr <= 5'd17;
        rd_en<= 1'b1;
      end
    else if(match_res[13])
      begin
        addr <= 5'd18;
        rd_en<= 1'b1;
      end
    else if(match_res[12])
      begin
        addr <= 5'd19;
        rd_en<= 1'b1;
      end
    else if(match_res[11])
      begin
        addr <= 5'd20;
        rd_en<= 1'b1;
      end
    else if(match_res[10])
      begin
        addr <= 5'd21;
        rd_en<= 1'b1;
      end
    else if(match_res[9])
      begin
        addr <= 5'd22;
        rd_en<= 1'b1;
      end
    else if(match_res[8])
      begin
        addr <= 5'd23;
        rd_en<= 1'b1;
      end
    else if(match_res[7])
      begin
        addr <= 5'd24;
        rd_en<= 1'b1;
      end
    else if(match_res[6])
      begin
        addr <= 5'd25;
        rd_en<= 1'b1;
      end
    else if(match_res[5])
      begin
        addr <= 5'd26;
        rd_en<= 1'b1;
      end
    else if(match_res[4])
      begin
        addr <= 5'd27;
        rd_en<= 1'b1;
      end
    else if(match_res[3])
      begin
        addr <= 5'd28;
        rd_en<= 1'b1;
      end
    else if(match_res[2])
      begin
        addr <= 5'd29;
        rd_en<= 1'b1;
      end
    else if(match_res[1])
      begin
        addr <= 5'd30;
        rd_en<= 1'b1;
      end
    else if(match_res[0])
      begin
        addr <= 5'd31;
        rd_en<= 1'b1;
      end
    else
      begin
        addr <= 5'd0;
        rd_en<= 1'b0;
      end
  else
  begin  
    addr <= 5'd0;
    rd_en<= 1'b0;
  end

assign addrb = (rd_en)?addr:5'd0; 
assign wea   = cpu_wen;
assign addra = ram_addr;

always@(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
       dina        <= 'b0;
    end
    else if(wea)begin
        case(addra[6:5])
          2'b01:
            dina <= {ram_data,53'b0};
          2'b10:
            dina <= {dina[84:53],ram_data,21'b0};
          2'b11:
            dina <= {dina[84:21],ram_data[20:0]};
          default: dina <= 0;
        endcase // addra[6:5]    
    end
end

always @(posedge clk or negedge rst_n) begin
  if(~rst_n) begin
    wea_ff      <= 0;
    ram_addra   <= 0;
    ram_addra_ff<= 0; 
  end 
  else begin
    wea_ff      <= wea;
    ram_addra   <= addra;
    ram_addra_ff<= ram_addra;
  end
end

always@(posedge clk or negedge rst_n) begin
    if(rst_n == 1'b0) begin
       read_data_cpu        <= 'b0;
       read_data_valid    <= 'b0;
    end
    else if(cpu_ren_ff)begin
        case(ram_addra_ff[6:5])
          2'b01:begin
            read_data_cpu      <= douta[84:53];
            read_data_valid    <= 1'b1;
          end
          2'b10:begin
            read_data_cpu      <= douta[52:21];
            read_data_valid    <= 1'b1;
          end
          2'b11:begin
            read_data_cpu      <= {11'b0,douta[20:0]};
            read_data_valid    <= 1'b1;
          end
          default:begin 
            read_data_cpu      <= read_data_cpu;
            read_data_valid    <= 'b0;
          end
        endcase // addra[6:5]    
    end
    else begin
      read_data_cpu      <= read_data_cpu;
      read_data_valid    <= 'b0;
    end
end

always @(posedge clk or negedge rst_n) begin
  if(~rst_n) begin
    cpu_ren_ff <= 0;
  end else begin
    cpu_ren_ff <= cpu_ren;
  end
end

action_ram_pkt_85 U_ram(
    .clka(clk),
    .wea(wea_ff),
    .rst_n(rst_n),
    .addra(ram_addra[4:0]),
    .dina(dina),
    .douta(douta),
    .clkb(clk),
    .web(1'b0),
    .addrb(addrb),
    .dinb(85'h0),
    .doutb(doutb)
    );
//*********************
endmodule    // hookup byte controller block
    
